/**********************************************************************************************************************
 *
 * Project:    mGameEngine
 * File:       tgaloader.cpp
 * Author:     karooolek
 * Created on: 2009-03-22
 *
 **********************************************************************************************************************/

#include "tgaloader.h"

namespace mGameEngine
{
namespace Graphics
{

TGALoader::TGALoader() :
    ImageLoader()
{
}

TGALoader::TGALoader(const String &filename) :
    ImageLoader(filename)
{
}

TGALoader::~TGALoader()
{
}

void TGALoader::load()
{
    // based on TARGA by Janusz Ganczarski
    // JanuszG@enter.net.pl
    // http://www.januszg.hg.pl

    // begin image loading
    _state = 0.0f;

    // delete old image
    if(_image)
    {
        delete _image;
        _image = NULL;
    }

    // open file for reading in binary mode
    FILE *file = fopen(_filename, "rb");
    if (!file)
    {
        return;
    }

    // read TGA header
    uint8 header[18];
    fread(header, 18, 1, file);

    // ommit ImageID field
    fseek(file, header[0], SEEK_CUR);

    // read data from header
    uint width = header[12] + (header[13] << 8);
    uint height = header[14] + (header[15] << 8);
    uint8 bpp = header[16];
    uint8 *data = NULL;

    // 32bit RGBA
    if(header[2] == 0x02 && bpp == 32)
    {
        data = new uint8[width * height * 4];
        fread((void*)data, width * height * 4, 1, file);

        // swizzle BGRA to RGBA
        for(uint x = 0; x < width * height * 4; x += 4)
        {
            uint8 temp = data[x];
            data[x] = data[x + 2];
            data[x + 2] = temp;
        }
    }

    // 24bit RGB
    else if(header[2] == 0x02 && bpp == 24)
    {
        data = new uint8[width * height * 3];
        fread((void*)data, width * height * 3, 1, file);

        // swizzle BGR -> RGB
        for(uint x = 0; x < width * height * 3; x += 3)
        {
            uint8 temp = data[x];
            data[x] = data[x + 2];
            data[x + 2] = temp;
        }
    }

    // 8b grayscale
    else if(header[2] == 0x03 && bpp == 8)
    {
        data = new uint8[width * height];
        fread((void*)data, width * height, 1, file);
    }

    // invalid image
    else
    {
        fclose(file);
        return;
    }

    // create new image
    _image = new Image(data, width, height, bpp);

    // close file
    fclose(file);
    delete[] data;

    // image is loaded
    _state = 1.0f;
}

}
}
